#include "cartoonnet.h"

CartoonNet::CartoonNet (const std::string modelpath, std::string id) {
    net = dnn::readNetFromONNX (modelpath.c_str ());
    net.setPreferableBackend (dnn::DNN_BACKEND_OPENCV);
    net.setPreferableTarget (dnn::DNN_TARGET_CPU);

    name = id;
    std::cout << modelpath << " 模型加载成功！" << std::endl;
}

CartoonNet::~CartoonNet () {}

void CartoonNet::Run (const Mat &input,Mat& output) {
    std::vector<int> inputShape = {1, input.rows, input.cols, 3};
    std::vector<int> outShape = {input.rows, input.cols, 3};
    Mat fblob;
    Mat outMat;
    input.convertTo (fblob, CV_32F, 1.0 / 127, -1.0);

    Mat blob(4,inputShape.data(),CV_32F,fblob.data);
    std::cout << "Blob形状: ";
    for (int i = 0; i < blob.dims; i++) {
        std::cout << blob.size[i] << " ";
    }
    std::cout << std::endl;
    //std::cout << blob << std::endl;
    net.setInput (blob);
    try {
        Mat out;
        net.forward (out);
        if (!out.empty ()) {
            std::cout << "Out形状: ";
            for (int i = 0; i < out.dims; i++) {
                std::cout << out.size[i] << " ";
            }
            std::cout << std::endl;
            blob.release();

            output.create(input.rows,input.cols,CV_8UC3);

            for(int y = 0;y < output.rows;y++) {
                for(int x = 0;x < output.cols;x++) {
                    uchar* dst = output.ptr<uchar>(y,x);
                    const float *src = out.ptr<float>(0,y,x);
                    float f = src[0];
                    if(f > 1.0f)
                        f = 1.0f;
                    else if(f < -1.0f)
                        f = -1.0f;
                    dst[0] = (f + 1.0f) * 127;

                    f = src[1];
                    if(f > 1.0f)
                        f = 1.0f;
                    else if(f < -1.0f)
                        f = -1.0f;
                    dst[1] = (f + 1.0f) * 127;

                    f = src[2];
                    if(f > 1.0f)
                        f = 1.0f;
                    else if(f < -1.0f)
                        f = -1.0f;
                    dst[2] = (f + 1.0f) * 127;

                }
            }


            // Mat batchOutput = out.reshape(0, input.rows*input.cols);
            // out = batchOutput.reshape(3, input.rows);

            // cv::resize(out, output, cv::Size(input.cols, input.rows));


            // //            std::cout << output << std::endl;
            // output.convertTo(output,CV_8UC3,127.5,1.0);
            //std::cout << output << std::endl;
            std::cout << "output形状: ";
            for (int i = 0; i < output.dims; i++) {
                std::cout << output.size[i] << " ";
            }
            std::cout << std::endl;

             std::cout << "output: (" << output.rows << "," << output.cols << ")"<< std::endl;
        }

    } catch (const cv::Exception &e) {
        std::cout << "推理失败，错误信息：" << e.what () << std::endl;
    }
    std::cout << "11 output: (" << output.rows << "," << output.cols << ")"<< std::endl;

}

#ifdef DEBUG_CARTOONNET
int main (int argc, char *argv[]) {
    CartoonNet cn ("model/anime/cartoon_h.onnx");
    Mat        image = imread ("out1.jpg");
    if (image.empty ()) {
        std::cerr << "无法加载图像" << std::endl;
        return -1;
    }
    Mat out = cn.Run (image);
    imwrite ("cartoon_h1.jpg", out);
    return 0;
}
#endif
// g++ -std=c++11 cartoonnet.cpp -o cartoon_h -DDEBUG_CARTOONNET=1
// -I/home/android/opencv/build/install/usr/local/include/opencv4 -L/home/android/opencv/build/install/usr/local/lib
// -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_shape -lopencv_highgui -lopencv_xobjdetect -lopencv_objdetect
// -lopencv_imgcodecs -lopencv_dnn -lopencv_imgproc -lopencv_core
//  export LD_LIBRARY_PATH=/home/android/opencv/build/install/usr/local/lib
